/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.p2psimulator.entity.overlaynetwork.structures;

import java.util.Random;
import java.util.Vector;
import org.p2psimulator.entity.Id;
import org.p2psimulator.entity.id.DoubleId;
import org.p2psimulator.entity.reputation.Reputation;
import org.p2psimulator.util.Tuple;

/**
 *
 * @author Amorim
 */
public class StormWitnessRing extends Ring<Reputation> {

    Vector<Id> vector;

    public StormWitnessRing(int M) {
        super(M);
        this.vector = new Vector<Id>();

    }

    public Id getRandomWitness() {
        if (vector.size() > 0) {
            Random r = new Random();
            int k = r.nextInt(vector.size());
            Id id  = vector.get(k);
            if (id==null){
                return new DoubleId(Double.NaN);
            }else{
                return id;
            }
        } else {
            return new DoubleId(Double.NaN);
        }
    }

    @Override
    public void clear() {
        super.clear();
        vector.clear();
    }

    @Override
    public void insertNode(Id<Double> key, Reputation value) {

        if (ring.size() >= maxSize){
            removeOlder();
        }
        // fifo
        vector.insertElementAt(key, 0);
        if (!ring.isEmpty()) {
            for (int i = 0; i < ring.size(); i++) {

                if (key.getValue() == ring.get(i).getA().getValue()) {
                    return;
                } else if (key.getValue() < ring.get(i).getA().getValue()) {

                    Tuple<Id<Double>, Reputation> tuple = new Tuple<Id<Double>, Reputation>(
                            key, value);
                    ring.add(i, tuple);
                    return;
                }
            }
        }
        ring.add(new Tuple<Id<Double>, Reputation>(
                key, value));
        return;
    }

    public Id removeOlder() {
        int s = vector.size();
        Id id = null;
        if (s > 0) {
            id = vector.remove(s - 1);
            for (int i = 0; i < ring.size(); i++) {
                if (id.getValue() == ring.get(i).getA().getValue()) {
                    ring.remove(i);
                }
            }
        }
        return id;
    }

    public boolean contains(Id key) {
        for (Tuple<Id<Double>, Reputation> t : ring) {
            if (t.getA().isEqual(key)) {
                return true;
            }
        }
        return false;

    }

    public boolean remove(Id key) {
        Tuple<Id<Double>, Reputation> r = null;
        for (Tuple<Id<Double>, Reputation> t : ring) {
            if (t.getA().isEqual(key)) {
                r = t;
            }
        }
        if (r != null) {
            return ring.remove(r);
        } else {
            return false;
        }
    }

    public int size() {
        return ring.size();
    }

    public Vector<Id> getWitnesses() {
        return vector;
    }
}
